﻿using System;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Threading;
using System.Windows.Forms;
using Client.Menus;
using Client.Model;
using Client.RemoteObjects;
using CommonTypes.Server;

namespace Client
{
    public class Client
    {
        private ClientData _clientData;

        public Client( String clientId, bool GUI )
        {
            _clientData = new ClientData( clientId, GUI );
        }

        public void Run( int port )
        {
            TcpChannel tcpChannel = new TcpChannel( port );
            ChannelServices.RegisterChannel( tcpChannel, false );

            ChannelDataStore tcpChannelData = ( ChannelDataStore )tcpChannel.ChannelData;
            String tcpChannelAddress = tcpChannelData.ChannelUris[ 0 ];

            GetServersFromFile( );

            ClientToClient clientToClient = new ClientToClient( _clientData );
            ServerToClient serverToClient = new ServerToClient( _clientData );

            RemotingServices.Marshal( clientToClient, "ClientToClient" );
            RemotingServices.Marshal( serverToClient, "ServerToClient" );

            PMToClient pmToClient = new PMToClient( _clientData, clientToClient, serverToClient );
            RemotingServices.Marshal( pmToClient, "PMToClient" );

            RegisterOnServer( tcpChannelAddress );

            if( _clientData.IsGUIPresent )
            {
                Application.EnableVisualStyles( );
                Application.SetCompatibleTextRenderingDefault( false );
                ClientMainMenu cmm = new ClientMainMenu( _clientData );
                Application.Run( cmm );
            }
            else
            {
                //Dont kill the main thread...
                while( true )
                {
                    Thread.Sleep( 999999 );
                }
            }
        }

        private void RegisterOnServer( String channelAddress )
        {
            bool registered = false;

            System.Console.WriteLine( "Registering id: {0}", _clientData.ClientId );
            while( !registered )
            {
                try
                {
                    registered = _clientData.GetRandomServer( ).RegisterClientLocation( _clientData.ClientId, channelAddress );
                }
                catch
                {
                    System.Console.WriteLine( "Error registering in server");
                }
            }
            System.Console.WriteLine( "Register Successful." );
        }

        private void GetServersFromFile( )
        {
            try
            {
                TextReader reader = new StreamReader( "..\\..\\Servers.txt" );

                for( int index = 0; index < 4; index++ )
                {
                    String serverId = reader.ReadLine( );
                    String serverAddress = reader.ReadLine( );

                    IClientToServer server = ( IClientToServer )Activator.GetObject( typeof( IClientToServer ), serverAddress + "/ClientToServer" );
                    _clientData.AddServerProxy( serverId, server );
                }
            }
            catch( FileNotFoundException )
            {
                Console.WriteLine( "The system was unable to find the file with the servers location. Please make shure that it is placed on the right place." );
                Console.WriteLine( "Press ENTER when you are ready." );
                Console.ReadLine( );
                GetServersFromFile( );
            }
        }
    }
}